﻿// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// Copyright (c) 2011, Dr. Masroor Ehsan
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the author nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 
// $Author: masroore@gmail.com $
// $Id: DseIntradayQuotesParserIronPython.cs 39 2011-10-23 07:44:27Z masroore@gmail.com $
// $Rev: 39 $
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using IronPython.Hosting;
using MaxTrader.BusinessObjects;
using MaxTrader.Core;
using MaxTrader.QuotesParser.Core;
using Microsoft.Scripting.Hosting;

namespace MaxTrader.IDQuotesParser.Dse.IronPython
{
    public class DseIntradayQuotesParserIronPython : IStockQuotesParser
    {
        private readonly List<RawStockQuote> _quotes;

        public DseIntradayQuotesParserIronPython()
        {
            _quotes = new List<RawStockQuote>();
        }

        #region IStockQuotesParser Members

        public StockQuoteType QuoteType
        {
            get { return StockQuoteType.Intraday; }
        }

        public StockExchange Exchange
        {
            get { return StockExchange.Dse; }
        }

        public string ParserClass
        {
            get { return "DSEBD_INTRADAY"; }
        }

        public string Name
        {
            get { return "Dsebd.org IronPython Intra-day Stock Quotes Parser"; }
        }

        public float Version
        {
            get { return 0.1f; }
        }

        public IEnumerable<RawStockQuote> Quotes
        {
            get { return _quotes; }
        }

        public bool ParseQuotes(Stream rawData)
        {
            Console.WriteLine(DateTime.Now);

            var scriptFile = Path.Combine(PathUtilities.GetPythonScriptsFolder(), "dse_intraday_clr.py");
            var compiledDll = Path.Combine(PathUtilities.GetPythonScriptsFolder(), "dse_intraday_clr.dll");

            var engine = Python.CreateEngine();
            var scope = File.Exists(compiledDll) ? LoadCompiledDll(engine, compiledDll) : LoadScript(engine, scriptFile);

            var IntradayClrAdapter = scope.GetVariable<Func<Stream, bool, object>>("IntradayClrAdapter");
            var pyObj = IntradayClrAdapter(rawData, false);
            var executeMethod = engine.Operations.GetMember<Func<List<RawStockQuote>>>(pyObj, "execute");
            var quotes = executeMethod();

            _quotes.Clear();
            quotes.ForEach(x => _quotes.Add(x));

            return true;
        }

        #endregion

        private ScriptScope LoadCompiledDll(ScriptEngine engine, string dllName)
        {
            Console.WriteLine("DLL");
            var asm = Assembly.LoadFile(Path.GetFullPath(dllName));
            engine.Runtime.LoadAssembly(asm);
            return engine.Runtime.ImportModule("dse_intraday_clr");
        }

        private ScriptScope LoadScript(ScriptEngine engine, string scriptFile)
        {
            Console.WriteLine("SCRIPT");
            var scope = engine.CreateScope();
            var source = engine.CreateScriptSourceFromFile(scriptFile);
            source.Compile();
            source.Execute(scope);
            return scope;
        }
    }
}